﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using LightCAD.MathLib;

namespace LightCAD.MathLib
{
    public class Circle2d : Curve2d
    {
        [JsonInclude]
        public Vector2 Center;
        public double Radius { get; set; }
        public override bool IsClosed { get => base.IsClosed; }
        public Circle2d()
        {
            this.Center = null;
            this.Type = Curve2dType.Circle2d;
            this.IsClosed = true;
        }
        public override void Copy(Curve2d src)
        {
            var cir = src as Circle2d;
            this.Center = cir.Center.Clone();
            this.Radius = cir.Radius;
            this.Name = cir.Name;
        }
        public override Curve2d Clone()
        {
            var newObj = new Line2d();
            newObj.Copy(this);
            return newObj;
        }
        public static Circle2d CreateCR(Vector2 center, double radius)
        {
            Circle2d cir = new Circle2d();
            cir.Center = center;
            cir.Radius = radius;
            return cir;
        }
        public override Curve2d Translate(Vector2 offset)
        {
            this.Center.Add(offset);
            return this;
        }

        public override Curve2d RotateAround(Vector2 basePoint, double angle)
        {
            this.Center.RotateAround(basePoint, angle);
            return this;
        }

        public override Curve2d Mirror(Vector2 axisStart, Vector2 axisDir)
        {
            this.Center.Mirror(axisStart, axisDir);
            return this;
        }
        public override Vector2[] GetPoints(int div = 5, double scaleInFuture = 1)
        {
            if (div <= 0)
            {
                div = (int)Math.Ceiling(this.Radius * scaleInFuture);
                if (div < 5)
                    div = 5;
            }
            var result = new Vector2[div + 1];
            for (int i = 0; i <= div; i++)
            {
                var delta = (double)i / div;
                result[i] = Ellipse2d.getEllipsePoint(this.Center, this.Radius, this.Radius, 0, Utils.TwoPI, 0, this.isClosed, delta);
            }
            return result;
        }

        public static Vector2 GetCrossCircleLine(Line2d line2D, Vector2 Center, double Radius)  //圆弧与直线的交点 重载调用
        {

            //计算直线的方向向量
            double dx = line2D.End.X - line2D.Start.X;
            double dy = line2D.End.Y - line2D.Start.Y;
            //计算直线的参数化方程
            double a = dx * dx + dy * dy;
            double b = 2 * (dx * (line2D.Start.X - Center.X) + dy * (line2D.Start.Y - Center.Y));
            double c = Math.Pow((line2D.Start.X - Center.X), 2) + Math.Pow((line2D.Start.Y - Center.Y), 2) - Math.Pow(Radius, 2);
            //计算判别式
            double discriminant = b * b - 4 * a * c;
            Vector2 point = new Vector2();
            if (discriminant >= 0)
            {
                if (Math.Abs(discriminant) < 1e-6)   //直线与圆只有一个切点
                {
                    double t = -b / (2 * a);
                    point = new Vector2(line2D.Start.X + t * dx, line2D.Start.Y + t * dy);
                }
                else                               //直线与圆有两个交点
                {
                    double t1 = (-b + (float)Math.Sqrt(discriminant)) / (2 * a);
                    double t2 = (-b - (float)Math.Sqrt(discriminant)) / (2 * a);
                    Vector2 point1 = new Vector2(line2D.Start.X + t1 * dx, line2D.Start.Y + t1 * dy);
                    Vector2 point2 = new Vector2(line2D.Start.X + t2 * dx, line2D.Start.Y + t2 * dy);
                    if (Vector2.Distance(point1, line2D.Start) < Vector2.Distance(point2, line2D.Start))
                    {
                        point = point1;
                    }
                    else
                    {
                        point = point2;
                    }
                }
            }
            return point;
        }

    }
}
